"use strict";

const path = require("path");
const pkgDir = require("pkg-dir").sync;
const pathExists = require("path-exists").sync;
const fsExtra = require("fs-extra");
const npminstall = require("npminstall");
const { isObject, pathFormate } = require("@pengsg-cli/util");
const log = require("@pengsg-cli/log");
const { getDefaultRegistry } = require("@pengsg-cli/get-npm-info");
const { getLatestNpmVersion } = require("@pengsg-cli/util/get-npm-info");

class Package {
  constructor(options) {
    if (!options) {
      throw new Error("Package构造参数必须填写");
    }
    if (!isObject(options)) {
      throw new Error("Package构造参数必须是对象类型");
    }
    this.storePath = options.storePath;
    this.targetPath = options.targetPath;
    this.packageName = options.packageName;
    this.packageVersion = options.packageVersion;
    //缓存路径前缀
    this.cacheFilePathPrefix = this.packageName.replace("/", "_");
  }

  get cacheFilePath() {
    return path.join(this.storePath,`_${this.cacheFilePathPrefix}@${this.packageVersion}@${this.packageName}`);
  }

  getSpecificFilePath(packageVersion) {
    return path.join(this.storePath,`_${this.cacheFilePathPrefix}@${packageVersion}@${this.packageName}`);
  }

  async _prepare() {
    // 自动生成缓存目录
    if (this.storePath && !pathExists(this.storePath)) {
      fsExtra.mkdirpSync(this.storePath);
    }
    // latest版本更新为具体的版本号
    if (this.packageVersion === "latest") {
      this.packageVersion = await getLatestNpmVersion(this.packageName);
    }
  }

  // 判断package是否存在
  async exist() {
    if (this.storePath) {
      await this._prepare();
      //获取包的缓存目录
      return pathExists(this.cacheFilePath);
    } else {
      return pathExists(this.targetPath);
    }
  }

  // 初始化package
  init() {}

  // 安装package
  install() {
    this._prepare();
    return npminstall({
      root: this.targetPath,
      storeDir: this.storePath,
      pkgs: [{ name: this.packageName, version: this.packageVersion }],
      registry: getDefaultRegistry(),
    });
  }

  // 更新package
  async update() {
    this._prepare();
    const latestPackageVersion = await getLatestNpmVersion(this.packageName);
    const latestFilePath = this.getSpecificFilePath(latestPackageVersion);
    if (latestFilePath && !pathExists(latestFilePath)) {
      await npminstall({
        root: this.targetPath,
        storeDir: this.storePath,
        pkgs: [{ name: this.packageName, version: latestPackageVersion }],
        registry: getDefaultRegistry(),
      });
      log.verbose(`更新成功，最新版本号为${latestPackageVersion}`)
      this.packageVersion = latestPackageVersion;
    }
  }

  _getRootFilePaths(targetPath) {
    // 获取package目录
    const pkgDirPath = pkgDir(targetPath);
    if (pkgDirPath) {
      // 获取package目录下的package.json
      const packageFile = require(path.join(pkgDirPath, "package.json"));
      if (packageFile && packageFile.main) {
        // 获取package.json中main字段路径
        const rootPath = path.resolve(pkgDirPath, packageFile.main);
        // 格式化路径
        return pathFormate(rootPath);
      }
    }
    return null;
  }

  // 获取package入口文件
  getRootFilePath() {
    if (this.storePath) {
        return this._getRootFilePaths(this.cacheFilePath);
    } else {
        return this._getRootFilePaths(this.targetPath);
    }
  }
}

module.exports = Package;
